package model;

import java.util.ArrayList;
import java.util.List;

import manager.IAnalizadorSintactico;
import manager.IToken;
import manager.ITokenStream;
import treelms.SimboloGenerico;
import visitors.BuildSymbolTableVisitor;

public class Bloque1 extends AbstractAnalizadorSintactico implements IAnalizadorSintactico {
	
	/* ATRIBUTOS */
	private List<SimboloGenerico> declaraciones = new ArrayList<SimboloGenerico>(); //Sintetizado
	
	/* INICIALIZACION */	
	public Bloque1 ( ITokenStream ts ) {
		super(ts, false);
	}
	public Bloque1 ( ITokenStream ts, boolean debugMode ) {
		super(ts,debugMode);
	}
	
	
	/** 
	 * Devuelve true si reconoce un bloque de procedimientos y funciones
	 */
	public boolean reconocer () {
		
		boolean recognized = true;
		
		/* <BLOQUE1> -> <HEADER> COMENZAR <SENTENCIA> <B'> |
		                                          adelantado |
		                LAMBDA
		*/

		if ( Header.primeros( this.getTokenSiguiente()) ) {
			
			/*		<BLOQUE1> -> <HEADER> COMENZAR <SENTENCIA> <B1>*/
		
			// Reconocer <HEADER>
			Header header = new Header(this.tokenStream, this.debugMode);
			recognized &= header.reconocer();
			this.setValidated(header.validado());
			
			this.declaraciones = header.getDeclaraciones();
			
			this.accept(BuildSymbolTableVisitor.getInstance());		//Crear el procedimiento, sus parametros y vars/consts/arreglos
			
			if ( !this.reconocerToken(IToken.PALABRA_RESERVADA_BEGIN) ) {
				return false;
			}
			
			// Reconocer Sentencia
			while ( Sentencia.primeros( this.getTokenSiguiente() ) ) {
				
				IAnalizadorSintactico sentencia = new Sentencia(this.tokenStream, this.debugMode);
				recognized &= sentencia.reconocer();
			}	

			while ( B1.primeros( this.getTokenSiguiente() ) ) {
				
				IAnalizadorSintactico b1 = new B1(this.tokenStream, this.debugMode);
				recognized &= b1.reconocer();
			}
			
		} else if ( !this.reconocerToken(IToken.PALABRA_RESERVADA_ADELANTADO) ) {
			return false;
		}
		
		return recognized;
	}
	
	public static boolean primeros(IToken token) {
		return  token.equals( new Token(IToken.PALABRA_RESERVADA_CONST) ) ||
				token.equals( new Token(IToken.PALABRA_RESERVADA_VAR) )||
				token.equals( new Token(IToken.PALABRA_RESERVADA_ADELANTADO)
				)
				/*||
				token.equals( new Token(IToken.PALABRA_RESERVADA_BEGIN))*/;
	}
	public List<SimboloGenerico> getDeclaraciones() {
		return declaraciones;
	}
}

